#pragma once
#include "vtsreadpin.hpp"
#include <list>

namespace VTSRead
{

class Outpin : public Pin, public IAsyncReader
{
    Outpin(const Outpin&);
    Outpin& operator=(const Outpin&);
    
public:

    Outpin(Filter*);
    virtual ~Outpin();
    
    //IUnknown interface:
    
    HRESULT STDMETHODCALLTYPE QueryInterface(const IID&, void**);
    ULONG STDMETHODCALLTYPE AddRef();
    ULONG STDMETHODCALLTYPE Release();
    
    //IPin interface:

    HRESULT STDMETHODCALLTYPE Connect(IPin*, const AM_MEDIA_TYPE*);

    //HRESULT STDMETHODCALLTYPE Disconnect();

    HRESULT STDMETHODCALLTYPE ReceiveConnection( 
        IPin*,
        const AM_MEDIA_TYPE*);
        
    HRESULT STDMETHODCALLTYPE QueryAccept(const AM_MEDIA_TYPE*);

    HRESULT STDMETHODCALLTYPE QueryInternalConnections( 
        IPin**,
        ULONG*);
        
    HRESULT STDMETHODCALLTYPE EndOfStream();

    //HRESULT STDMETHODCALLTYPE BeginFlush();    
    //HRESULT STDMETHODCALLTYPE EndFlush();
    
    HRESULT STDMETHODCALLTYPE NewSegment( 
        REFERENCE_TIME,
        REFERENCE_TIME,
        double);
        
    //IAsyncReader
    
    HRESULT STDMETHODCALLTYPE RequestAllocator( 
        IMemAllocator*,
        ALLOCATOR_PROPERTIES*,
        IMemAllocator**);
    
    HRESULT STDMETHODCALLTYPE Request( 
        IMediaSample*,
        DWORD_PTR);
    
    HRESULT STDMETHODCALLTYPE WaitForNext( 
        DWORD,
        IMediaSample**,
        DWORD_PTR*);
    
    HRESULT STDMETHODCALLTYPE SyncReadAligned( 
        IMediaSample*);
    
    HRESULT STDMETHODCALLTYPE SyncRead( 
        LONGLONG,
        LONG,
        BYTE*);
    
    HRESULT STDMETHODCALLTYPE Length( 
        LONGLONG*,
        LONGLONG*);
    
    HRESULT STDMETHODCALLTYPE BeginFlush();
    HRESULT STDMETHODCALLTYPE EndFlush();    
    
private:

    struct ReadInfo
    {
        IMediaSample* m_pSample;
        DWORD_PTR m_user;
        
        ReadInfo() : m_pSample(0), m_user(0)
        {
        }
        
        ReadInfo(IMediaSample* p, DWORD_PTR u) :
            m_pSample(p),
            m_user(u)
        {
        }
        
        ReadInfo(const ReadInfo& rhs) :
            m_pSample(rhs.m_pSample),
            m_user(rhs.m_user)
        {
        }

    private:
        ReadInfo& operator=(const ReadInfo&);
    };
    
    typedef std::list<ReadInfo> read_queue_t;
    
    read_queue_t m_read_queue;
    ALLOCATOR_PROPERTIES m_props;
    
    bool m_bFlush;
    
};
    
}  //end namespace VTSRead
